/*
 * Copyright 2012 Martin Zitnik.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cz.muni.fi.heathtow.web.pages;

import cz.muni.fi.heathrowapi.DestinationService;
import cz.muni.fi.heathrowapi.HeathrowRoles;
import cz.muni.fi.heathrowapi.dto.DestinationDTO;
import cz.muni.fi.heathtow.web.auth.SecureWicketAuthenticatedWebSession;
import cz.muni.fi.heathtow.web.validation.DestinationBean;
import cz.muni.fi.heathtow.web.validation.UniqueDestinationCodeValidator;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormValidatingBehavior;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.authroles.authorization.strategies.role.Roles;
import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.markup.html.form.RequiredTextField;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.link.AbstractLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.AbstractItem;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.repeater.RepeatingView;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.util.string.StringValue;
import org.apache.wicket.util.time.Duration;
import org.apache.wicket.validation.validator.StringValidator;

/**
 *
 * @author Martin Zitnik
 */
public class DestinationView extends MainPage {

    @SpringBean(name = "destinationService")
    private DestinationService destinationService;
    public static final String PARAM_EDIT = "edit";

    public DestinationView(final PageParameters parameters) {
        super(parameters);

        showAll();

        StringValue editId = parameters.get(PARAM_EDIT);
        final DestinationDTO editDestination = editId != null && !editId.isEmpty() ? destinationService.getDestination(editId.toLongObject()) : new DestinationDTO();

        if (editDestination.getId() != null) {
            renderEditForm(editDestination).add(new Label("heading", new StringResourceModel("form.editDestLegend", this, null))).add(new TextField("isEdditing", Model.of("1")));
        } else {
            renderEditForm(editDestination).add(new Label("heading", new StringResourceModel("form.createDestLegend", this, null))).add(new TextField("isEdditing", Model.of("0")));
        }

        Component show = new AbstractLink("showForm") {
        };
        add(show);
        MetaDataRoleAuthorizationStrategy.authorize(show, RENDER, HeathrowRoles.ADMIN);

        Label info = new Label("info", new StringResourceModel("info", this, null));
        add(info);
        info.setVisible(SecureWicketAuthenticatedWebSession.get().getRoles().equals(new Roles()));

        Component header = new AbstractItem("header");
        add(header);
        MetaDataRoleAuthorizationStrategy.authorize(header, RENDER, HeathrowRoles.USER);        
    }

    private void showAll() {

        final RepeatingView repeatingView = new RepeatingView("repeating");
        MetaDataRoleAuthorizationStrategy.authorize(repeatingView, RENDER, HeathrowRoles.USER);
        add(repeatingView);

        Label connectionError = new Label("error", new StringResourceModel("error", this, null));
        add(connectionError);
        connectionError.setVisible(false);
        
        try {
            for (final DestinationDTO destination : destinationService.findAll()) {
                AbstractItem item = new AbstractItem(repeatingView.newChildId());

                item.add(new Label("id", String.valueOf(destination.getId())));
                item.add(new Label("city", destination.getCity()));
                item.add(new Label("code", destination.getCode()));
                item.add(new Label("state", destination.getState()));
                item.add(new Label("stateCode", destination.getStateCode()));
                Link editLink = new Link("editLink") {
                    @Override
                    public void onClick() {
                        PageParameters parameters = new PageParameters();
                        parameters.add(PARAM_EDIT, destination.getId().toString());
                        setResponsePage(DestinationView.class, parameters);

                    }
                };
                MetaDataRoleAuthorizationStrategy.authorize(editLink, RENDER, HeathrowRoles.ADMIN);
                item.add(editLink);
                
                Link deleteLink = new Link("deleteLink") {
                    @Override
                    public void onClick() {
                        destinationService.deleteDestination(destination);
                        setResponsePage(new DestinationView(new PageParameters()));
                    }
                };
                MetaDataRoleAuthorizationStrategy.authorize(deleteLink, RENDER, HeathrowRoles.ADMIN);
                item.add(deleteLink);

                repeatingView.add(item);
            }
        } catch (Exception ex) {
            Logger.getLogger(DestinationView.class.getName()).log(Level.SEVERE, null, ex);
            connectionError.setVisible(!SecureWicketAuthenticatedWebSession.get().getRoles().equals(new Roles()));
        }



    }

    private Form renderEditForm(final DestinationDTO destinationDTO) {
        
        final FeedbackPanel feedback = new FeedbackPanel("feedback");
        feedback.setOutputMarkupId(true);
        add(feedback);
        
        DestinationBean bean = new DestinationBean();
        Form<DestinationBean> form = new Form<DestinationBean>("editForm", new CompoundPropertyModel<DestinationBean>(bean));
        add(form);
        form.setOutputMarkupId(true);
        
        FormComponent<String> codeField = new RequiredTextField<String>("editCode", new PropertyModel<String>(destinationDTO, "code")).add(StringValidator.maximumLength(4));
        codeField.setLabel(new ResourceModel("view.code"));
        codeField.add(new UniqueDestinationCodeValidator(destinationDTO.getId()));
        FormComponent<String> cityField = new RequiredTextField<String>("editCity", new PropertyModel<String>(destinationDTO, "city")).add(StringValidator.maximumLength(255));
        cityField.setLabel(new ResourceModel("view.city"));
        FormComponent<String> stateField = new RequiredTextField<String>("editState", new PropertyModel<String>(destinationDTO, "state")).add(StringValidator.maximumLength(255));
        stateField.setLabel(new ResourceModel("view.state"));
        FormComponent<String> stateCodeField = new RequiredTextField<String>("editStateCode", new PropertyModel<String>(destinationDTO, "stateCode")).add(StringValidator.maximumLength(4));
        stateCodeField.setLabel(new ResourceModel("view.stateCode"));
        
        AjaxButton sumbitButton = new AjaxButton("submitButton") {
            @Override
            public void onSubmit(AjaxRequestTarget target, Form<?> form) {
                if (destinationDTO.getId() == null) {
                    destinationService.createDestination(destinationDTO);
                    setResponsePage(new DestinationView(new PageParameters()));
                } else {
                    destinationService.updateDestination(destinationDTO);
                    setResponsePage(new DestinationView(new PageParameters()));
                }
            }
            
            @Override
            protected void onError(AjaxRequestTarget target, Form<?> form) {
                target.add(feedback);
            }
        };

        Button cancelButton = new Button("cancelButton") {
            @Override
            public void onSubmit() {
                setResponsePage(new DestinationView(new PageParameters()));
            }
        };
        cancelButton.setDefaultFormProcessing(false); 

        AjaxFormValidatingBehavior.addToAllFormComponents(form, "onkeyup", Duration.ONE_SECOND);
        
        MetaDataRoleAuthorizationStrategy.authorize(form, RENDER, HeathrowRoles.ADMIN);

        form.add(codeField, cityField, stateField, stateCodeField, cancelButton, sumbitButton);
        
        return form;
    }
}
